/*
 * A simple boot in C
 */
 
#include "multiboot.h"
#include "gdt.h"
#include "idt.h"
#include "pic.h"
#include "println.h"
#include "teclado.h"

void kernel_main(unsigned long magic, multiboot_info_t *mbinfo)
{
	multiboot_info_t *mbi;
	module_t *mod;
	char* buf;
	int i;
	
	init_GDT();
	init_IDT();
	pic_init();
	
	sti(); //habilita interrupções (cli() dessabilita as interrupções)

	init_pages_map();
	char *c = (char*) alloc_pages();
	char *d = (char*) alloc_pages();

if(magic != MULTIBOOT_BOOTLOADER_MAGIC){
		printLine("Invalid magic Number.");
		return;
	}
	
	printLine("Printing some kernel info.");
	printLine(" ");

	
	/*Printing the Magic Number*/
	itoa(magic, buf);
	printLine("Magic Number:");
	printLine(buf);
	
	mbi = mbinfo;
	
	/*Printing the Flags*/
	itoa(mbi->flags, buf);
	printLine("Flags:");
	printLine(buf);
	
	/*Printing Memory Boundaries.*/
	itoa(mbi->mem_lower, buf);
	printLine("Memory Lower (kB):"); 
	printLine(buf);
	itoa(mbi->mem_upper, buf);
	printLine("Memory Upper (kB):");
	printLine(buf);
	
	/*Printing the boot device*/
	itoa(mbi->boot_device, buf);
	printLine("Boot Device:");
	printLine(buf);
	
	/*Printing CMDLINE*/
	itoa(mbi->cmdline, buf);
	printLine("cmdline:");
	printLine(buf);
	
	printLine(" ");
	printLine("Press any button to show the Mods.");
	readLine(c);
	printLine(" ");
	
	/*Printing Mods*/
	itoa((int)mbi->mods_count, buf);
	printLine("Mods Count:");
	printLine(buf);
	itoa((int)mbi->mods_addr, buf);
	printLine("Mods Address:");
	printLine(buf);
	
	for (i = 0, mod = (module_t *) mbi->mods_addr; i < mbi->mods_count; i++, mod++){
		itoa((unsigned)mod->mod_start, buf);
		printLine("Mod Start:");
		printLine(buf);
		itoa((unsigned)mod->mod_end, buf);
		printLine("Mod End:");
		printLine(buf);
		printLine("String:");
		printLine((char *)mod->string);
	}
	
	printLine(" ");
	printLine("Press any button to show the a.out table symbol.");	
	readLine(c);
	printLine(" ");
	
	/* Printing symbol table of a.out*/
	aout_symbol_table_t *aout_sym = &(mbi->u.aout_sym);
	printLine("aout symbol table:");
	printLine("tabsize:");
	itoa((unsigned) aout_sym->tabsize, buf);
	printLine(buf);
	printLine("strsize:");
	itoa((unsigned) aout_sym->strsize, buf);
	printLine(buf);
	printLine("address:");
	itoa((unsigned) aout_sym->addr, buf);
	printLine(buf);
	
	printLine(" ");
	printLine("Press any button to show the Elf Section.");
	readLine(c);
	printLine(" ");
	
	/*Printing the section header table of ELF*/
	elf_section_header_table_t *elf_sec = &(mbi->u.elf_sec);
	printLine("Elf Section:");
	printLine("Num:");
	itoa((unsigned) elf_sec->num, buf);
	printLine(buf);
	printLine("Size:");
	itoa((unsigned) elf_sec->size, buf);
	printLine(buf);
	printLine("Address:");
	itoa((unsigned) elf_sec->addr, buf);
	printLine(buf);
	printLine("shndx:");
	itoa((unsigned) elf_sec->shndx, buf);
	printLine(buf);
	
	printLine(" ");
	printLine("Press any button to show the Memory map.");
	readLine(c);
	printLine(" ");

	/*Printing the Memory Map.*/
	memory_map_t *mmap;
	printLine("Memory map:");
	printLine("mmap address:");
	itoa((unsigned) mbi->mmap_addr, buf);
	printLine(buf);
	printLine("mmap lenght:");
	itoa((unsigned) mbi->mmap_length, buf);
	printLine(buf);

	for (mmap = (memory_map_t *) mbi->mmap_addr;
				(unsigned long) mmap < mbi->mmap_addr + mbi->mmap_length;
			mmap = (memory_map_t *) ((unsigned long) mmap
									+ mmap->size + sizeof (mmap->size))){
		printLine("size:");
		itoa((unsigned) mmap->size, buf);
		printLine(buf);
		printLine("base address high:");
		itoa((unsigned) mmap->base_addr_high, buf);
		printLine(buf);
		printLine("base address low:");
		itoa((unsigned) mmap->base_addr_low, buf);
		printLine(buf);
		printLine("length high:");
		itoa((unsigned) mmap->length_high, buf);
		printLine(buf);
		printLine("length low:");
		itoa((unsigned) mmap->length_low, buf);
		printLine(buf);
		printLine("type:");
		itoa((unsigned) mmap->type, buf);
		printLine(buf);
	}
	printLine(" ");
	printLine("plpso Initialized!");
	printLine(" ");

	for(;;){
		readLine(c);
		printLine(c);

	}
}
